package org.qloudgen.borg.pages;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.time.Duration;
import org.qloudgen.borg.CommonValues;
import org.qloudgen.borg.beans.Cluster;
import org.qloudgen.borg.cluster.operator.HadoopClusterOperatorImpl;
import org.qloudgen.borg.cluster.operator.IClusterOperator;
import org.qloudgen.borg.metadb.DefaultImpl;
import org.qloudgen.borg.pages.common.BasePage;
import org.qloudgen.borg.pages.model.ClusterModel;

import com.google.common.collect.Lists;

@SuppressWarnings("unchecked")
public class ClusterListPage extends BasePage{

	/**
	 * @Author youngeryoyo
	 * youngeryoyo@gmail.com
	 */

	static Log log = LogFactory.getLog(ClusterListPage.class);

	private static final long serialVersionUID = 1L;
	private transient List<Cluster> clusters = Lists.newArrayList();
	private transient ClusterModel dsm;
	private transient String buttonName;
	private transient FileUpload upload;
	
	public ClusterListPage(PageParameters pageParameters){
		
		super();
		this.pp = pageParameters;
		
		// get userno's clusters from metadb
		DefaultImpl.getClusterList(clusters);

		final FileUploadField image = new FileUploadField("image");
		image.setOutputMarkupId(true);
		
		// add form 
		@SuppressWarnings("rawtypes")
		Form<?> form = new Form("clusterform",new CompoundPropertyModel<ClusterModel>(new ClusterModel())) {
			
			private static final long serialVersionUID = 1L;

			@Override
			protected void onSubmit() {
				
				dsm = (ClusterModel)getDefaultModelObject();
				buttonName = ((FormComponent<String>)findSubmittingButton()).getInputName();
				upload = image.getFileUpload();
					
				if (dsm.getGroup() == null) {
					
					info(CommonValues.INFO_NO_SELECT);
					
				} else {
					
					// add buttonName  to pp
					if (pp.getPosition("buttonName") < 0 ){
						pp.add("buttonName",buttonName);
					} else {
						pp.set("buttonName",buttonName);
					}

					// add clusterID  to pp
					String clusterID = String.valueOf(dsm.getGroup().getClusterID());
					if (pp.getPosition("clusterID") < 0){
						pp.add("clusterID",clusterID);
					} else {
						pp.set("clusterID",clusterID);
					}
					
					processHandler();
					
				}
			
			}
			
		};
		this.add(form);
		form.add(image);
	
		// add group
		final RadioGroup<?> group=new RadioGroup<Object>("group"); 
		group.setOutputMarkupId(true);
		group.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(CommonValues.LIST_REFRESH_TIME)){	
			
			private static final long serialVersionUID = 1L;
			
			@Override
			protected  void	onPostProcessTarget(AjaxRequestTarget target)  {
				DefaultImpl.getClusterList(clusters);	
				target.add(group);	
			}
			
		});
		group.setRenderBodyOnly(false);
		form.add(group);
		
		// add cluster list
		final PageableListView<Cluster> listView =new PageableListView<Cluster>( "rows", clusters, CommonValues.SHOW_LIST_NUMBER) {

			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(ListItem<Cluster> item) {
				final Cluster cluster = (Cluster) item.getModelObject();
				item.add(new Radio<Cluster>("radio", new Model<Cluster>(cluster)));
				item.add( new Label( "id", String.valueOf(cluster.getClusterID())));
				item.add( new Label( "name", cluster.getClusterName()));
				item.add( new Label( "desc", cluster.getClusterDesc()));
				item.add( new Label( "status", CommonValues.statusNames.get(cluster.getClusterStatus())));
				item.add( new Label( "isavailable", CommonValues.statusNames.get(cluster.getIsAvailable())));
				item.add( new Label( "masterip", cluster.getMasterIp()));
				item.add( new Label( "sysuser", cluster.getSysUser()));
				item.add( new Label( "createtime", cluster.getCreateTime()));
				item.add( new Label( "starttime", cluster.getStartTime()));
				
				if (item.getIndex() % 2 == 1) {
					item.add(new AttributeModifier("class",new Model<String>("even")));
					} else {
					item.add(new AttributeModifier("class",new Model<String>("odd")));
					}
			}
		};
		listView.setOutputMarkupId(true);
		group.add(listView);
		
		// add navigator
		final AjaxPagingNavigator nav = new AjaxPagingNavigator("navigator", listView);
		nav.setOutputMarkupId(true);
		group.add(nav);
		
		// add button 
		form.add(new Button("start"));
		form.add(new Button("stop"));
		form.add(new Button("pause"));
		form.add(new Button("delete"));
		form.add(new Button("add").setVisible(false));
		form.add(new Button("remove").setVisible(false));
		form.add(new Button("modify"));
		
		form.add(new Button("uploadJar"));
		
		// add refresh
		form.add(new AjaxLink<Object>("refresh"){
			private static final long serialVersionUID = 1L;
			public void onClick(AjaxRequestTarget target) {
				DefaultImpl.getClusterList(clusters);
				target.add(group);
			}
		});		
	
	}

	protected void processHandler() {

		Cluster cluster = dsm.getGroup();
		IClusterOperator operator = new HadoopClusterOperatorImpl(cluster,buttonName);
				
		int flag = CommonValues.clusterOperators.get(buttonName);
		
		switch (flag) {
			case 1 : {
				
					if ( cluster.getClusterStatus().equals(CommonValues.STATUS_ON)) {
						
						info(cluster.getClusterName() + CommonValues.INFO_CLUSTER_RUNNING);
						return;
					} 
					break;
				}
			case 2: {
				
					if ( cluster.getClusterStatus().equals(CommonValues.STATUS_OFF)) {
						
						info(cluster.getClusterName() + CommonValues.INFO_CLUSTER_STOPPED);
						return;
					}
					break;
				}
			case 4:
			case 5: {
				
					if ( !cluster.getClusterStatus().equals(CommonValues.STATUS_ON)) {
						
						info(cluster.getClusterName() + CommonValues.INFO_CLUSTER_RUN);
						return;
					} 
					setResponsePage(CommonValues.pages.get(buttonName), pp);
					return;
				}
			case 7: {
				
					if ( upload == null || StringUtils.isEmpty(upload.getClientFileName())) {
						
						info(cluster.getClusterName() + CommonValues.INFO_SELECT_FILE);
						return;
					}
						
					try {
						String localJar = CommonValues.getTempDir() + (CommonValues.osType.equals(CommonValues.OSTYPE_LINUX)?"/":"\\") 
								+ upload.getClientFileName();
						
						upload.writeTo(new File(localJar));
						cluster.setLocalJar(localJar);
						
						switch (operator.handler()) {
							case 0:info(CommonValues.INFO_UPLOAD_COMPLETED + cluster.getClusterName());break;
							default: error(CommonValues.ERROR_UPLOAD_FILE);
						}
						
					} catch (IOException e) {
						log.error(e.getMessage());
						error(CommonValues.ERROR_UPLOAD_FILE);
					}
					return;
				}
			case 8: {
				
				setResponsePage(CommonValues.pages.get(buttonName), pp);
				return;
			}
		}
		
		operator.handler();
		setResponsePage(CommonValues.pages.get(buttonName), pp);

	}
}
